Skip to content

Fixes text centering causing offsets by some glyphs#31412

Open
dotMorten wants to merge 2 commits into
dotnet:mainfrom
dotMorten:patch-3
Open

Fixes text centering causing offsets by some glyphs#31412
dotMorten wants to merge 2 commits into
dotnet:mainfrom
dotMorten:patch-3

Conversation

@dotMorten
Copy link
Copy Markdown
Contributor

@dotMorten dotMorten commented Aug 29, 2025

Description of Change

The font alignment calculation was wrong, often causing the symbols to be offset when rendering using FontImageSource.

Issues Fixed

Fixes #30004

Below is an example of the adjustment. First column using <Label /> to render the Glyph, second is how MAUI currently renders it, and 3rd column with the fix applied. I applied a background to the two images, to make it clear that the generated image sizes hasn't changed, only the alignment within them.
image

Copilot AI review requested due to automatic review settings August 29, 2025 18:54
@dotMorten dotMorten requested a review from a team as a code owner August 29, 2025 18:54
@dotnet-policy-service dotnet-policy-service Bot added the community ✨ Community Contribution label Aug 29, 2025
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Hey there @@dotMorten! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes text centering issues in FontImageSource rendering on Windows that was causing glyph offsets. The fix updates the positioning calculation to properly center glyphs within the canvas.

  • Replaces incorrect DrawBounds-based positioning with proper canvas centering calculation
  • Uses LayoutBounds and DefaultFontSize for more accurate text positioning

…ceService.Windows.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@dotMorten
Copy link
Copy Markdown
Contributor Author

@clandrew @shawnhar This is the best I could come up with to fix the text centering issue, but you two might be the best ones to confirm the use of CanvasTextLayout and calculating centering. Would appreciate your input on this. I didn't really find anything else in the layout that gave the values needed to correctly center the symbol.

@sheiksyedm
Copy link
Copy Markdown
Contributor

/azp run MAUI-UITests-public

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@MauiBot
Copy link
Copy Markdown
Collaborator

MauiBot commented Mar 22, 2026

🤖 AI Summary

📊 Expand Full Reviewe29d763 · Update src/Core/src/ImageSources/FontImageSourceService/FontImageSourceService.Windows.cs
🔍 Pre-Flight — Context & Validation

Issue: #30004 - "FontImageSource not center-aligned inside Image control in .NET MAUI"
PR: #31412 - Fixes text centering causing offsets by some glyphs
Platforms Affected: Windows
Files Changed: 1 implementation, 0 test

Key Findings

  • The linked issue is explicitly verified on Windows and the PR changes only src/Core/src/ImageSources/FontImageSourceService/FontImageSourceService.Windows.cs, so this is a Windows-specific fix.
  • The issue discussion includes a reproducer and notes that some glyphs are visibly offset when FontImageSource is compared against Label rendering of the same font glyph.
  • The PR discussion indicates the author chose a CanvasTextLayout-based centering calculation and asked Windows-focused reviewers to validate the centering math.
  • No dedicated test files were changed in this PR, and no prior agent-style review artifact was found in the PR discussion.
  • Related edge-case context from the issue thread: a hardcoded -2 vertical adjustment appeared to help in a repro but was acknowledged as an incomplete explanation, and a separate blur observation was addressed with Aspect="Center" rather than this code path.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #31412 Replace the previous DrawBounds-based 1px-offset positioning with a canvas-center calculation derived from layout.LayoutBounds and layout.DefaultFontSize. ⏳ PENDING (Gate) src/Core/src/ImageSources/FontImageSourceService/FontImageSourceService.Windows.cs Original PR

🚦 Gate — Test Verification

Gate Result: ⚠️ SKIPPED

Platform: android (requested)
Mode: Full Verification

  • Tests FAIL without fix: ❌
  • Tests PASS with fix: ❌

Reason: PR #31412 does not include UI/device test coverage for issue #30004, and the bug is explicitly Windows-specific while the requested Android platform is unaffected. Existing repository matches for FontImageSource are generic service tests rather than an issue-focused verification path for this glyph-centering bug, so a meaningful fail-without-fix/pass-with-fix gate could not be established in this environment.


🔧 Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix (claude-opus-4.6) Use Math.Max(LayoutBounds, DrawBounds) for canvas sizing, then geometrically center DrawBounds via canvas-center minus draw-bounds center. ⚠️ BLOCKED 1 file Blocked by Linux host lacking workable Windows targeting packages.
2 try-fix (claude-sonnet-4.6) Give CanvasTextLayout explicit fontSize x fontSize dimensions and rely on Win2D's built-in center alignment, drawing at origin with no manual offsets. ⚠️ BLOCKED 1 file Different from PR math and attempt 1, but still blocked on Linux.
3 try-fix (gpt-5.3-codex) Use LayoutBounds as the centering frame: size the canvas from LayoutBounds (+padding) and place the layout at canvas center - layout bounds center. ⚠️ BLOCKED 1 file Avoids DefaultFontSize heuristics and DrawBounds centering, but blocked on Linux.
4 try-fix (gemini-3-pro-preview) Convert the text layout to CanvasGeometry, compute the exact ink bounds, and render via FillGeometry with a translated offset based on geometry bounds. ⚠️ BLOCKED 1 file Distinct vector-geometry strategy; blocked on Linux.
5 try-fix (claude-opus-4.6, round 2) Use CanvasTextLayout.LineMetrics baseline/height data to center typographic metrics instead of visual bounds. ⚠️ BLOCKED 1 file Metric-driven strategy; blocked because Windows TFMs are not available from this Linux environment.
6 try-fix (gpt-5.3-codex, round 2) Two-pass DrawBounds-sized layout: measure first, then create a second layout whose box matches the measured ink bounds and let Win2D center within that box. ⚠️ BLOCKED 1 file Different built-in-centering variant; blocked on Linux.
7 try-fix (claude-opus-4.6, round 3) Render to an offscreen bitmap, scan alpha pixels for visual bounds/centroid, then offset the final draw to center the actual rendered ink. ⚠️ BLOCKED 1 file First post-render pixel-analysis strategy; blocked on Linux.
8 try-fix (claude-sonnet-4.6, round 3) Use the font's CapHeight metric via CanvasFontFace as the vertical centering reference instead of line height or rendered bounds. ⚠️ BLOCKED 1 file Cap-height strategy implemented with fallback behavior; blocked on Linux.
9 try-fix (gpt-5.3-codex, round 3) Shape text to glyph IDs and use per-glyph font-table metrics to compute centering offsets directly from typographic data. ⚠️ BLOCKED 1 file Most font-table-driven strategy; blocked on Linux.
PR PR #31412 Replace the prior DrawBounds + 1px offset math with canvas center + LayoutBounds + DefaultFontSize / 2. ⚠️ UNVERIFIED 1 file Original PR; Gate was skipped because no applicable automated verification path was available.

Cross-Pollination

Model Round New Ideas? Details
claude-opus-4.6 2 Yes Suggested font-metrics / baseline-centered alignment.
claude-sonnet-4.6 2 No NO NEW IDEAS
gpt-5.3-codex 2 Yes Suggested two-pass DrawBounds-sized layout using Win2D built-in centering.
gemini-3-pro-preview 2 No NO NEW IDEAS
claude-opus-4.6 3 Yes Suggested offscreen render + alpha-bounds centroid centering.
claude-sonnet-4.6 3 Yes Suggested cap-height-based vertical alignment.
gpt-5.3-codex 3 Yes Suggested glyph-shaping / per-glyph font metrics centering.
gemini-3-pro-preview 3 No NO NEW IDEAS

Exhausted: Yes
Selected Fix: PR #31412 (tentative) — no alternative candidate could be empirically validated on this Linux host, and none produced a passing verification result that would justify preferring it over the PR.


📋 Report — Final Recommendation

⚠️ Final Recommendation: REQUEST CHANGES

Phase Status

Phase Status Notes
Pre-Flight ✅ COMPLETE Windows-only FontImageSource centering bug tied to issue #30004; PR changes one Windows implementation file and no tests.
Gate ⚠️ SKIPPED Requested platform was Android, but the bug is Windows-specific and no issue-focused verification path exists in the PR.
Try-Fix ✅ COMPLETE 9 attempts completed, 0 passing, all blocked by Linux-host Windows-targeting limitations.
Report ✅ COMPLETE

Summary

PR #31412 addresses a real Windows glyph-centering problem in FontImageSource, and the proposed math is plausible. However, this review could not establish fail-without-fix/pass-with-fix coverage, and no empirical winner emerged from the mandatory alternative-fix exploration because the affected code only compiles under Windows-targeted builds while this review environment is Linux.

Root Cause

The bug appears to come from how Windows FontImageSourceService positions text within the generated canvas: the previous implementation sized from DrawBounds and then applied a fixed 1px-offset formula that does not reliably center all glyphs. The PR changes that to a LayoutBounds/DefaultFontSize-based centering formula, but without test coverage or Windows validation here, correctness remains unproven.

Fix Quality

The PR is small and targeted, which is good, but it currently lacks the evidence needed for approval:

  • No issue-focused automated test was added for "FontImageSource not center-aligned inside Image control in .NET MAUI" #30004.
  • Gate verification could not run meaningfully on the requested Android platform because the defect is Windows-only.
  • The repo itself gates Windows target frameworks behind IsOSPlatform('windows') in Directory.Build.props, which is why every alternative attempt was blocked on this Linux host rather than producing a comparable pass/fail result.

Given that, the next step should be to add or identify a Windows verification path and validate the PR on a Windows-capable environment before approving.


@MauiBot MauiBot added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Mar 22, 2026
Copy link
Copy Markdown
Contributor

@kubaflo kubaflo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is good! But could you please try to add a test for this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community ✨ Community Contribution s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"FontImageSource not center-aligned inside Image control in .NET MAUI"

5 participants